package com.wskeee.ec.components
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import com.wskeee.ec.core.SkinableComponent;
	
	public class TrackBase extends SkinableComponent
	{
		public static const VERTICAL:String = "vertical";
		public static const HORIZONTAL:String = "horizontal";
		
		public var info:Object;
		
		public function TrackBase(dir:String)
		{
			this.dir = dir;
			super();
		}
		
		//========================= initSkin ====================
		override protected function initSkin():void
		{
			super.initSkin();
			initSkinPark();
		}
		//========================= end =========================
		
		//========================= skinpark ====================
		//按下thumb时MouseX,MouseY,记录以在 onThumbMouseMove 计算thumb移动值
		protected var lastMouseDownPoint:Point;
		//增加/减少 值
		protected var clickTrackIncrease:Boolean;
		protected var clickTrackTargetValue:Number;
		
		protected function initSkinPark():void
		{
			track.addEventListener(MouseEvent.MOUSE_DOWN,onTrackMouseDown);
			thumb.addEventListener(MouseEvent.MOUSE_DOWN,onThumbMouseDown);
		}
		
		protected function onThumbMouseDown(event:MouseEvent):void
		{
			_isDraging = true;
			lastMouseDownPoint = new Point(thumb.mouseX,thumb.mouseY);
			stage.addEventListener(MouseEvent.MOUSE_MOVE,onThumbMouseMove);
			stage.addEventListener(MouseEvent.MOUSE_UP,onThumbMouseUp);
		}
		
		protected function onThumbMouseUp(event:MouseEvent):void
		{
			_isDraging = false;
			stage.removeEventListener(MouseEvent.MOUSE_MOVE,onThumbMouseMove);
			stage.removeEventListener(MouseEvent.MOUSE_UP,onThumbMouseUp);
		}
		
		protected function onThumbMouseMove(event:MouseEvent):void
		{
			var p:Point = new Point(track.mouseX,track.mouseY);
			var tempValue:Number = (p[info.xy]*track[info.scaleXY] - lastMouseDownPoint[info.xy])/(track[info.wh] - thumb[info.wh])*(maximum-minimum)
			setValue(tempValue); 
		}
		
		protected function onTrackMouseDown(evt:MouseEvent):void
		{
			//计算需要滚动到的位置
			clickTrackTargetValue = (track[info.mouseXY]*track[info.scaleXY])/(track[info.wh] - thumb[info.wh])*(maximum-minimum);
			//计算是增加/减少 值
			clickTrackIncrease = clickTrackTargetValue > value;
			stage.addEventListener(Event.ENTER_FRAME,onTrackEnterFrame);
			stage.addEventListener(MouseEvent.MOUSE_UP,onTrackMouseUp);
		}
		
		protected function onTrackMouseUp(event:MouseEvent):void
		{
			stage.removeEventListener(Event.ENTER_FRAME,onTrackEnterFrame);
			stage.removeEventListener(MouseEvent.MOUSE_UP,onTrackMouseUp);
		}
		
		protected function onTrackEnterFrame(event:Event):void
		{
			if(!track.hitTestPoint(stage.mouseX,stage.mouseY,true))return;
			value += stepSize *(clickTrackIncrease ? 1 : -1);
			if(clickTrackIncrease)
			{
				if(value>=clickTrackTargetValue || value>=maximum)onTrackMouseUp(null);
			}else
			{
				if(value<=clickTrackTargetValue || value<=minimum)onTrackMouseUp(null);
			}
		}
		
		protected function destroyTrackEvent():void
		{
			track.removeEventListener(MouseEvent.MOUSE_DOWN,onTrackMouseDown);
			thumb.removeEventListener(MouseEvent.MOUSE_DOWN,onThumbMouseDown);
		}
		//========================= end =========================
		
		
		//========================= invaidate ===================
		override protected function commitProperties():void
		{
			super.commitProperties();
			if(maximumChangedFlag)
			{
				maximumChangedFlag = false;
				setValue(value);
				invalidateDisplayList();
			}
		}
		//========================= end =========================
		
		
		
		
		//========================= act =========================
		/**
		 * 设置值 
		 * @param value
		 * 
		 */
		protected function setValue(value:Number):void
		{
			var str:String = snapInterval.toString();
			var digit:int = 1;
			if(snapInterval<1)
				digit = Math.pow(10,str.substr(str.indexOf(".")+1).length);
			value = Math.round(Math.round(value/snapInterval)*snapInterval*digit)/digit;
			if(isNaN(value))value = 0;
			if(value<minimum)value = minimum;
			if(value>maximum)value = maximum;
			if(_value == value)return;
			
			_value = value;
			onChange();
			invalidateProperties();
			invalidateDisplayList();
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		protected function onChange():void
		{
			//override
			
		}
		
		override public function destory():void
		{
			destroyTrackEvent();
			super.destory();
		}
		//========================= end =========================
		
		
		
		
		
		//========================= properties ==================
		//---------------------
		//dir
		//---------------------
		private var _dir:String;
		/**
		 * 方向
		 * @param value  vertical/horizontal
		 * 
		 */
		public function set dir(value:String):void
		{
			_dir = value;
			info = (dir == VERTICAL) ? 
				{wh:"height", xy:"y",mouseXY:"mouseY",scaleXY:"scaleY"} : {wh:"width", xy:"x",mouseXY:"mouseX",scaleXY:"scaleX"};
		}
		public function get dir():String
		{
			return _dir;
		}
		//---------------------
		//minimum
		//---------------------
		private var _minimum:Number = 0;
		/**
		 * 最小值 
		 * @param value
		 * 
		 */
		public function set minimum(value:Number):void
		{
			_minimum = value;
			setValue(value);
		}
		public function get minimum():Number
		{
			return _minimum;
		}
		//---------------------
		//maximum
		//---------------------
		protected var maximumChangedFlag:Boolean = false;
		private var _maximum:Number = 100;
		/**
		 * 最大值 
		 * @param value
		 * 
		 */
		public function set maximum(value:Number):void
		{
			_maximum = value;
			//if(snapInterval>value)
				//snapInterval = value;
			maximumChangedFlag = true;
			invalidateProperties();
		}
		public function get maximum():Number
		{
			return _maximum;
		}
		//---------------------
		//snapInterval 
		//---------------------
		private var _snapInterval:Number = 1;
		/**
		 * track每次更改有效值
		 * @param value
		 * 
		 */
		public function set snapInterval(value:Number):void
		{ 
			if(value<=0 || isNaN(value))value = 1;
			_snapInterval = value;
		}
		public function get snapInterval():Number
		{
			return _snapInterval;
		}
		//---------------------
		//stepSize
		//---------------------
		private var _stepSize:Number = 20;
		/**
		 * 滑块
		 * @param value
		 * 
		 */
		public function set stepSize(value:Number):void
		{
			_stepSize = value;
		}
		public function get stepSize():Number
		{
			return _stepSize<snapInterval ? snapInterval : _stepSize;
		}
		//---------------------
		//value
		//---------------------
		private var _value:Number = 0;
		/**
		 * 当前值 
		 * @param value = minimum ~ maximum
		 * 
		 */
		public function set value(value:Number):void
		{
			setValue(value);
		}
		public function get value():Number
		{
			return _value;
		}
		//---------------------
		//isDraging
		//---------------------
		private var _isDraging:Boolean;
		/**
		 * 当前处于拖曳状态 
		 * @return 
		 * 
		 */
		public function get isDraging():Boolean
		{
			return _isDraging;
		}
		//========================= end =========================
		
		//========================= skin ========================
		protected function get thumb():Sprite
		{
			return Object(skinDrawer).thumb;
		}
		
		protected function get track():Sprite
		{
			return Object(skinDrawer).track;
		}
		
		override public function get DefaultSkinDrawer():Class
		{
			return null;
		}
		//========================= end =========================
	}
}